package com.moonshineproject.plugin.haxe.haxeproject
{
	import com.moonshineproject.events.AddTabEvent;
	import com.moonshineproject.events.CloseTabEvent;
	import com.moonshineproject.events.FilePluginEvent;
	import com.moonshineproject.events.NewProjectEvent;
	import com.moonshineproject.events.OpenFileEvent;
	import com.moonshineproject.plugin.PluginBase;
	import com.moonshineproject.plugin.haxe.haxeproject.exporter.HaxeFlashDevelopExporter;
	import com.moonshineproject.plugin.haxe.haxeproject.importer.HaXeFlashDevelopImporter;
	import com.moonshineproject.plugin.haxe.haxeproject.vo.HaXeProjectVO;
	import com.moonshineproject.plugin.project.event.ProjectEvent;
	import com.moonshineproject.plugin.project.vo.ProjectVO;
	import com.moonshineproject.plugin.settings.SettingsView;
	import com.moonshineproject.plugin.settings.vo.ISetting;
	import com.moonshineproject.plugin.settings.vo.PathSetting;
	import com.moonshineproject.plugin.settings.vo.SettingsWrapper;
	import com.moonshineproject.plugin.settings.vo.StaticLabelSetting;
	import com.moonshineproject.plugin.settings.vo.StringSetting;
	import com.moonshineproject.plugin.templating.TemplatingHelper;
	import com.moonshineproject.utils.Utils;
	
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.filesystem.File;

	public class HaXeProjectPlugin extends PluginBase
	{
		override public function get name():String 			{return "HaXe Project Plugin";}
		override public function get author():String 		{return "Moonshine Project Team";}
		override public function get description():String 	{return "HaXe project importing, exporting & scaffolding.";}
		
		protected var templateLookup:Object = {};
		
		override public function activate():void
		{
			super.activate();
			
			dispatcher.addEventListener(FilePluginEvent.EVENT_FILE_OPEN, handleFileOpen);
			dispatcher.addEventListener(NewProjectEvent.CREATE_NEW_PROJECT, createProject);
		}
		
		override public function deactivate():void
		{	
			super.deactivate();
			
			dispatcher.removeEventListener(FilePluginEvent.EVENT_FILE_OPEN, handleFileOpen);
			dispatcher.removeEventListener(NewProjectEvent.CREATE_NEW_PROJECT, createProject);
		}
		
		// If user opens project file, open project automagically
		protected function handleFileOpen(event:FilePluginEvent):void
		{
			if (event.file.extension == 'hxproj') // FlashDevelop haXe project file ending 
			{
				// Is file in an already opened project?
				for each (var p:ProjectVO in model.projects)
				{
					if ( event.file.nativePath.indexOf(p.folder.nativePath) == 0 )
					{
						return;
					}
				}
				
				// Assume user wants to open project by clicking settings file
				event.preventDefault();
				var rootPath:String = Utils.getDirectoryPathFor(event.file);
				var root:File = new File(rootPath);
				event.preventDefault();
				
				openProject(root, event.file);
			}
		}
		
		protected function openProject(root:File, projectFile:File):void
		{
			var p:HaXeProjectVO;
			p = HaXeFlashDevelopImporter.parse(projectFile);
			p.projectFile = projectFile;
			
			// Don't open a project twice
			for each (var pr:ProjectVO in model.projects)
			{
				if (pr.folder.nativePath == p.folder.nativePath)
				{
					model.activeProject = pr;
					return;
				}
			}
			
			// Set as active project
			model.activeProject = p;

			// Add to tree view
			dispatcher.dispatchEvent(
				new ProjectEvent(ProjectEvent.ADD_PROJECT, p)
			);
		}
		
		protected function createProject(event:NewProjectEvent):void
		{
			// Only create haXe projects.
			if (event.projectFileEnding != "hxproj") return;
			
			var project:HaXeProjectVO = HaXeFlashDevelopImporter.parse(event.settingsFile);
			project.projectName = "New " + event.templateDir.name;
			
			project.folder = File.documentsDirectory;
			
			// Create settings view to get initial name & location
			var settingsView:SettingsView = new SettingsView();
			settingsView.defaultSaveLabel = "Create";
			
			settingsView.addEventListener(SettingsView.EVENT_SAVE, createSave);
			settingsView.addEventListener(SettingsView.EVENT_CLOSE, createClose);
				 
			settingsView.addCategory("");
				 				
			var settings:SettingsWrapper = new SettingsWrapper("Name & Location", Vector.<ISetting>([
				new StaticLabelSetting("New " + event.templateDir.name),
				new StringSetting(project, 'projectName', 'Project Name'),
				new PathSetting(project, 'folderPath', 'Project Directory', true)
			]));
			
			settingsView.addSetting(settings, "");
			
			settingsView.label = "New Project";
			settingsView.associatedData = project;
			
			dispatcher.dispatchEvent(
				new AddTabEvent(settingsView)
			);
			
			templateLookup[project] = event.templateDir;
		}
		
		// Also called by createSave to clean up
		private function createClose(event:Event):void
		{
			var settings:SettingsView = event.target as SettingsView;
			
			settings.removeEventListener(SettingsView.EVENT_CLOSE, createClose);
			settings.removeEventListener(SettingsView.EVENT_SAVE, createSave);
			
			delete templateLookup[settings.associatedData];
			
			dispatcher.dispatchEvent(
				new CloseTabEvent(CloseTabEvent.EVENT_CLOSE_TAB, event.target as DisplayObject)
			);
		}
		
		private function createSave(event:Event):void
		{
			var view:SettingsView = event.target as SettingsView;
			var pvo:HaXeProjectVO = view.associatedData as HaXeProjectVO;
			
			var templateDir:File = templateLookup[pvo];
			
			var projectName:String = pvo.projectName;
			var targetFolder:File = pvo.folder;
			
			// Create project root directory
			targetFolder = targetFolder.resolvePath(projectName);
			targetFolder.createDirectory();
			
			// Time to do the templating thing!
			var th:TemplatingHelper = new TemplatingHelper();
			th.templatingData["$ProjectName"] = projectName;
			th.templatingData["$Settings"] = projectName;
			th.projectTemplate(templateDir, targetFolder);
			
			// Figure out which one is the settings file
			var settingsFile:File = targetFolder.resolvePath(projectName+".hxproj");
			
			// Set some stuff to get the paths right
			pvo = HaXeFlashDevelopImporter.parse(settingsFile);
			pvo.projectName = projectName;
			
			// Write settings
			HaxeFlashDevelopExporter.export(pvo, settingsFile); 
			
			dispatcher.dispatchEvent(
				new ProjectEvent(ProjectEvent.ADD_PROJECT, pvo)
			);
			
			// Close settings view
			createClose(event);
			
			// Open main file for editing
			dispatcher.dispatchEvent( 
				new OpenFileEvent(OpenFileEvent.OPEN_FILE, pvo.targets[0])
			);
		}
	}
}